#include "Game.h"

string curMap;
wz::node curMapNode;
vector<Game::Foothold*> footholds;
bool running;
int last_delta;
int delta;
double fps;
bool keystates[1000];
///////////////////////////////////////////////////////////////
// Foothold stuff
///////////////////////////////////////////////////////////////
Game::Foothold::Foothold(double _x1, double _y1, double _x2, double _y2) : x1(_x1), y1(_y1), x2(_x2), y2(_y2) {//I need to extend this constructor with the other argument types.
	//I will now practice typing properly. It feels kinda weird...
	footholds.push_back(this);
}
Game::Foothold::~Foothold(){
	for(auto i = footholds.begin(); i!=footholds.end(); i++){
		if(*i==this){
			footholds.erase(i);
		}
	}
}
void Game::Foothold::draw(){
	//glTranslated(-view.x,-view.y,0);
	//glBegin(GL_LINES);
	//glColor4f(1,1,1,1);
	//glVertex2d(x1,y1);
	//glVertex2d(x2,y2);
	//glEnd();
	//glLoadIdentity();
}
///////////////////////////////////////////////////////////////
// The primary stuff
///////////////////////////////////////////////////////////////
bool Game::init(string path){
#ifdef ONLINE
	Network::ignite();
#endif
	path.erase(path.find_last_of("\\")+1);
//#ifdef _DEBUG
	wz::init("C:\\Nexon\\MapleStory");
//#else
	//wz::init(path);
//#endif

	try {
		wz::load("Base");
		wz::load("Character");
		wz::load("Effect");
		wz::load("Etc");
		wz::load("Item");
		wz::load("List");
		wz::load("Map");
		wz::load("Mob");
		wz::load("Morph");
		wz::load("Npc");
		wz::load("Quest");
		wz::load("Reactor");
		wz::load("Skill");
		// Wzlib has problems loading sound
#ifdef WZLIB_SOUND_ENABLED
		wz::load("Sound");
#endif
		wz::load("String");
		wz::load("TamingMob");
		wz::load("UI");
	} catch (...) {
		std::cerr<<"Error loading WZ Files"<<std::endl;
		std::cin.get();
		exit(1);
	}
	init_graphics();
	Mouse::init();
	load_map("100000000");
	running = true;
	last_delta = SDL_GetTicks();
	fps = 100;
	cout << "Done loading!" << endl;
	return true;
}

bool Game::loop(){
	handle_input();
	SDL_FillRect(screen,NULL,0);
	for(auto i = objects.begin(); i!=objects.end(); i++){
		(*i)->draw();
	}
	draw_text(tostring(fps), 0, 0);
	Mouse::draw();
	SDL_Flip(screen);
	int temp = SDL_GetTicks();
	delta = temp - last_delta;
	last_delta = temp;
	fps = (1000/max(delta,1)+fps*4)/5;
	//cout << fps << endl;
	return running;
}
void Game::handle_input(){
	SDL_Event event;
	while(SDL_PollEvent(&event)){
		if(event.type == SDL_QUIT){
			running = false;
		} else if (event.type == SDL_KEYDOWN) {
			keystates[event.key.keysym.sym] = true;
		} else if (event.type == SDL_KEYUP) {
			keystates[event.key.keysym.sym] = false;
		} else if (event.type == SDL_MOUSEMOTION) {
			Mouse::x = event.motion.x;
			Mouse::y = event.motion.y;
			//std::cout<<"Mouse: "<<Mouse::x<<" "<<Mouse::y<<std::endl;
		} else if (event.type == SDL_MOUSEBUTTONDOWN) {
			Mouse::state = Mouse::State::PRESSED;
		} else if (event.type == SDL_MOUSEBUTTONUP) {
			Mouse::state = Mouse::State::NORMAL;
		}
	}
	if(keystates[SDLK_UP]){
		view.y-=5;
	}
	if(keystates[SDLK_DOWN]){
		view.y+=5;
	}
	if(keystates[SDLK_LEFT]){
		view.x-=5;
	}
	if(keystates[SDLK_RIGHT]){
		view.x+=5;
	}
	if(keystates[SDLK_RETURN]){
		string id;
		cout << "Enter the map id: " << endl;
		cin >> id;
		load_map(id);
	}
}
void Game::unload(){
#ifdef ONLINE
	Network::shutdown();
#endif
	SDL_Quit();
	TTF_Quit();
}

///////////////////////////////////////////////////////////////
// Loading stuff
///////////////////////////////////////////////////////////////
void Game::load_map(string id){
	while(id.size()<9){
		id = "0"+id;
	}
	cout << "Loading map " << id;
	char mapZone = id[0];
	cout << " in zone " << mapZone << endl;
	wz::node& mapNode = wz::top["Map"]["Map"][string("Map")+mapZone][id];
	if(!mapNode){
		return;
	}
	curMap = id;
	curMapNode = mapNode;
	objects.clear();
	footholds.clear();
	load_footholds();
	load_tiles();
	load_objs();
}

void Game::load_footholds(){
	wz::node fhnode = curMapNode["foothold"];
	cout << "Loading footholds..." << endl;
	for(auto i = fhnode.begin(); i!=fhnode.end(); i++){
		int fhdepth = atoi(i->first.c_str());
		for(auto j = i->second.begin(); j!=i->second.end(); j++){
			int fhgroup = atoi(j->first.c_str());
			for(auto k = j->second.begin(); k!=j->second.end(); k++){
				wz::node& fh = k->second;
				new Game::Foothold(fh["x1"],fh["y1"],fh["x2"],fh["y2"]);
			}
		}
	}
}
void Game::load_tiles(){
	for(auto i=0;i<8;i++){
		wz::node layernode = curMapNode[tostring(i)];
		string type = layernode["info"]["tS"];
		for(auto j=0; layernode["tile"][tostring(j)]; j++){
			wz::node tilenode = layernode["tile"][tostring(j)];
			string u = tilenode["u"];
			string no = tostring((int)tilenode["no"]);
			wz::node tiledata = wz::top["Map"]["Tile"][type][u][no];
			tile* ntile = new tile;
			ntile->spr = tiledata;
			ntile->x = tilenode["x"];
			ntile->y = tilenode["y"];
			ntile->z = i;
			ntile->z = depth::tile;
			ntile->z = tilenode["zM"];
			ntile->z = tiledata["z"];
			ntile->sort();
		}
	}
}
void Game::load_objs(){
	for(auto i=0;i<8;i++){
		wz::node layernode = curMapNode[tostring(i)];
		for(auto j=0; layernode["obj"][tostring(j)]; j++){
			wz::node objnode = layernode["obj"][tostring(j)];
			string type1 = objnode["oS"];
			string type2 = objnode["l0"];
			string type3 = objnode["l1"];
			string type4 = objnode["l2"];
			//cout << type1 << "," << type2 << "," << type3 << "," << type4 << endl;
			wz::node objdata = wz::top["Map"]["Obj"][type1][type2][type3][type4]["0"];
			obj* nobj = new obj;
			nobj->spr = objdata;
			nobj->x = objnode["x"];
			nobj->y = objnode["y"];
			nobj->z = i;
			nobj->z = depth::obj;
			nobj->z = objnode["z"];
			nobj->z = objdata["z"];
			nobj->sort();
		}
	}
}